home *** CD-ROM | disk | FTP | other *** search
- /*
- ** Apple Macintosh Developer Technical Support
- **
- ** Program: CShell
- ** File: docursor.c
- ** Written by: Eric Soldan
- **
- ** Copyright © 1990-1991 Apple Computer, Inc.
- ** All rights reserved.
- */
-
-
-
- /*****************************************************************************/
-
-
-
- #include "CShell.h" /* Get the CShell includes/typedefs, etc. */
- #include "CShellCommon.h" /* Get the stuff in common with rez. */
- #include "CShell.protos" /* Get the prototypes for CShell. */
-
- #ifndef __TEXTEDITCONTROL__
- #include "TextEditControl.h"
- #endif
-
- #ifndef __TOOLUTILS__
- #include <ToolUtils.h>
- #endif
-
- #ifndef __UTILITIES__
- #include "Utilities.h"
- #endif
-
-
-
- /*****************************************************************************/
-
-
-
- RgnHandle gCurrentCursorRgn;
- /* The current cursor region. The initial cursor region is an empty
- ** region, which will cause WaitNextEvent to generate a mouse-moved
- ** event, which will cause us to set the cursor for the first time.
- */
-
- Cursor *gCurrentCursor, **gCurrentCursorHndl;
- /* The current cursor that applies to gCurrentCursorRgn. These values
- ** are here to shorten the re-processing time for determining the
- ** correct cursor after an event. This is specifically so that characters
- ** can be typed into the TextEdit control faster. If we spend a great
- ** deal of time per-event recalculating the cursor region, text entry for
- ** the TextEdit control slows down considerably. If you want to override
- ** the time savings because you are changing the cursor directly, either
- ** set gCurrentCursor to nil, or call DoSetCursor to set the cursor.
- ** DoSetCursor simply sets gCurrentCursor to nil, as well as setting
- ** the cursor.
- */
-
-
-
- /*****************************************************************************/
- /*****************************************************************************/
-
-
-
- /* Handle the cursor changes, based on if an AppleEvent is involved, or
- ** depending on the location of the cursor. This also calculates the region
- ** where the current cursor resides (for WaitNextEvent). If the mouse is
- ** ever outside of that region, an event would be generated, causing this
- ** function to be called, allowing us to change the region to the region
- ** the mouse is currently in. The only other cursor management in this sample
- ** is for operations such as pulling down a menu. Just prior to pulling down
- ** the menu, the arrow cursor is set. This prevents any latencies in cursor
- ** update to cause a non-arrow cursor to be used in the menus. This technique
- ** should be carried throughout the application.
- */
-
- #pragma segment Main
- void DoCursor(Boolean isAppleEvent, long classID)
- {
- WindowPtr window, oldPort;
- RgnHandle rgn;
- Rect outBoxRct, teViewRct;
- Point mouseLoc;
- short cursorID;
- TEHandle outBox, teHndl;
- FileRecHndl frHndl;
- ControlHandle viewCtl;
-
- mouseLoc = GetGlobalMouse();
-
- if ((!gInBackground) && (!IsDAWindow(window = FrontWindow()))) {
-
- if (isAppleEvent) {
-
- /* Handle the cursor for Apple Events. */
-
- switch (classID) {
- case kAEOpenApplication: cursorID = oappCursor; break;
- case kAEOpenDocuments: cursorID = odocCursor; break;
- case kAEPrintDocuments: cursorID = pdocCursor; break;
- case kAEQuitApplication: cursorID = quitCursor; break;
- case kAEAnswer: cursorID = ansrCursor; break;
- case 'wait': cursorID = watchCursor; break;
- }
-
- SetRectRgn(gCurrentCursorRgn, kExtremeNeg, kExtremeNeg,
- kExtremePos, kExtremePos);
- DoSetCursor(*GetCursor(cursorID));
- }
-
- else { /* Handle the cursor for non-AppleEvent situations. */
-
- if (IsAppWindow(window)) {
-
- if (gCurrentCursor) {
- if (PtInRgn(mouseLoc, gCurrentCursorRgn)) {
- SetCursor(*gCurrentCursorHndl);
- return;
- }
- }
-
- frHndl = (FileRecHndl)GetWRefCon(window);
- viewCtl = CTEViewFromTE(outBox = (*frHndl)->doc.outBox);
- outBoxRct = (*viewCtl)->contrlRect;
-
- GetPort(&oldPort);
- SetPort(window);
- LocalToGlobalRect(&outBoxRct);
- SetPort(oldPort);
-
- if (CTETargetInfo(&teHndl, &teViewRct) == window) {
- if ((teHndl == outBox) && (PtInRect(mouseLoc, &outBoxRct))) {
- RectRgn(gCurrentCursorRgn, &outBoxRct);
- SetCursor(*(gCurrentCursorHndl = GetCursor(ibeamCursor)));
- return;
- }
- }
- SetRectRgn(gCurrentCursorRgn, kExtremeNeg, kExtremeNeg,
- kExtremePos, kExtremePos);
- rgn = NewRgn();
- RectRgn(rgn, &outBoxRct);
- DiffRgn(gCurrentCursorRgn, rgn, gCurrentCursorRgn);
- DisposeRgn(rgn);
- }
-
- DoSetCursor(&QD(arrow));
- }
- }
-
- else {
- SetRectRgn(gCurrentCursorRgn, kExtremeNeg, kExtremeNeg,
- kExtremePos, kExtremePos);
- gCurrentCursor = nil;
- }
- }
-
-
-
- /*****************************************************************************/
-
-
-
- #pragma segment Main
- void DoSetCursor(Cursor *cursor)
- {
- if (cursor) SetCursor(cursor);
- gCurrentCursor = nil;
- if (!cursor) DoCursor(false, 0);
- }
-
-
-
-